﻿/*
 * 接口类。所有的操作基于此类
 * c
 */

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Collections;

namespace Genesis
{
    /// <summary>
    /// C#语言的genesis脚本编程接口
    /// </summary>
    public class Genesis
    {
        /// <summary>
        /// genesis命令行的字符前缀 DIR_PREFIX
        /// </summary>
        private const string DIR_PREFIX = "@%#%@";
        private string _STATUS;
        private string _READANS;
        private string _PAUSANS;
        private string _MOUSEANS;
        private string _COMANS;
        private string _GENESIS_DIR;
        private string _GENESIS_EDIR;
        private string _csh_file;
        private Dictionary<string, string[]> do_info;
        
        public Genesis()
        {
            ///类初始化的时候设置环境变量
            _GENESIS_DIR = getENV("GENESIS_DIR");
            _GENESIS_EDIR = getENV("GENESIS_EDIR");
        }

        /// <summary>
        /// 获取当前JOB
        /// </summary>
        public string JOB { get=> getENV("JOB"); }
     

        /// <summary>
        /// 获取当前STEP
        /// </summary>
        public string STEP { get => getENV("STEP"); }
   

        /// <summary>
        /// 获取状态值
        /// </summary>
        public string STATUS { get=> _STATUS; }
        public string READANS { get=> _READANS; }
        public string PAUSANS { get => _PAUSANS; }
        public string MOUSEANS { get => _MOUSEANS; }
        public string COMANS { get => _COMANS; }
        public string GENESIS_DIR{ get => _GENESIS_DIR;}
        public string GENESIS_EDIR { get => _GENESIS_EDIR; }
        public string Csh_file { get => _csh_file; }




        /// <summary>
        /// 发送命令到Pipe中
        /// </summary>
        public void SendCommandToPipe(string commandType, string command)
        {

            Console.WriteLine($"{DIR_PREFIX}{commandType} {command}");
        }

        /// <summary>
        /// 执行COM命令
        /// </summary>
        /// <param name="values"></param>
        public void COM(params string[] values)
        {
            string command = string.Empty;

            if(values.Length == 1)   //如果仅执行不带参数的命令的话，则直接取第一个命令即可
            {
                command = values[0];
                SendCommandToPipe("COM", removeNewLines(command));
            }else    //否则依次解析数组
            {
                command = conectCommandString(values);   
                SendCommandToPipe("COM", command);
            }

            _STATUS = getReply();
            _READANS = getReply();
            _COMANS = _READANS;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void PAUSE()
        {
            SendCommandToPipe("PAUSE", "");
            _STATUS = getReply();
            _READANS = getReply();
            _PAUSANS = getReply();
        }

        public void SU_OFF()
        {
            SendCommandToPipe("SU_OFF", "");
        }

        public void SU_ON()
        {
            SendCommandToPipe("SU_ON", "");
        }

        public void VOF()
        {
            SendCommandToPipe("VOF", "");
        }

        public void VON()
        {
            SendCommandToPipe("VON", "");
        }

        public void MOUSE()
        {
            SendCommandToPipe("MOUSE r", "");
            _STATUS = getReply();
            _READANS = getReply();
            _MOUSEANS = getReply();
        }

        public void AUX(params string[] values)
        {
            string command = string.Empty;
            if (values.Length == 1)
            {
                command = values[0];
                ///单个参数的时候，恐怕末尾有回车\n，这里在发送命令前将其剔除
                SendCommandToPipe("AUX", removeNewLines(command));
            }else
            {
                command = conectCommandString(values);
                SendCommandToPipe("AUX", command);
            }
            _STATUS = getReply();
            _READANS = getReply();
            _COMANS = _READANS;
        }

        /// <summary>
        /// 连接参数成为一个完整的字符串
        /// </summary>
        /// <param name="commands"></param>
        /// <returns></returns>
        private string conectCommandString(string[] commands)
        {
            string commandString = string.Empty;
            foreach (string item in commands)
            {
                commandString += $"{item},";
            }
            //除去最后一位的逗号
            return commandString.TrimEnd(',');
        }
        /// <summary>
        /// 回车替换成空格
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        private string removeNewLines(string command)
        {
            return command.Replace("\n", " ");
        }


        /// <summary>
        /// 获取信息
        /// </summary>
        /// <param name="entity_path"></param>
        /// <param name="entity_type"></param>
        /// <param name="data_type"></param>
        /// <param name="parameter"></param>
        /// <param name="serial_number"></param>
        /// <param name="options"></param>
        /// <param name="help"></param>
        /// <param name="units"></param>
        /// <param name="parses"></param>
        /// parses默认为true,默认解析genesis生成的信息文件,解析成功后会删除信息文件。但如果获取的信息文件为坐标或其他类型不需要解析的是偶
        /// 次参数设置为flase
        public void DO_INFO(string entity_path = "", string entity_type = "", string data_type = "",
         string parameter = "", string serial_number = "", string options = "", string help = "",
         string units = "inch", Boolean parses = true)
        {

            string _entity_path, _entity_type, _data_type, _parameter, _serial_number, _options, _help;
            string info_pre, info_com;
            

            _COMANS = "-1";
            if (entity_path != "")
            {
                _entity_path = $"-e {entity_path}";
            }
            else
            {
                _entity_path = "";
            }

            if (entity_type != "")
            {
                _entity_type = $"-t {entity_type}";
            }
            else
            {
                _entity_type = "";
            }

            if (data_type != "")
            {
                _data_type = $"-d {data_type}";
            }
            else
            {
                _data_type = "";
            }

            if (parameter != "")
            {
                _parameter = $"-p {parameter}";
            }
            else
            {
                _parameter = "";
            }
            if (serial_number != "")
            {
                _serial_number = $"-s {serial_number}";
            }
            else
            {
                _serial_number = "";
            }
            if (options != "")
            {
                _options = $"-o {options}";
            }
            else
            {
                _options = "";
            }
            if (help != "")
            {
                _help = "-help";
            }
            else
            {
                _help = "";
            }

            Random rd = new Random();
            //生成的随机数由1-9999之间加上时间的毫微秒数组成。保证短时间生成的信息文件名是不重复的。
            _csh_file = $"{_GENESIS_DIR}/share/tmp/info_csh.{rd.Next(9999)}{DateTime.Now.Ticks.ToString()}";
            info_pre = $"info,out_file={_csh_file},write_mode=replace,units={units} ,args=";
            info_com =
                $"{info_pre} {_entity_type} {_entity_path} {_data_type} {_parameter} {_serial_number} {_options} {_help}";
           
            parse(info_com, _csh_file, parses);

        }

        public void parse(string INFOcommand,string csh_file,Boolean parsers)
        {
            COM(INFOcommand, "");
            //分析为真的时候才开始分析，否则不分析。
            if(parsers == true)
            {
                StreamReader sr = new StreamReader(csh_file, Encoding.Default);
                string line;
                //需要去除的字符。
                Char[] chrTrim = { ' ', '(', ')' };
                do_info = new Dictionary<string, string[]>();
                while ((line = sr.ReadLine()) != null)
                {
                    line.Trim();
                    if (line == "") continue;
                    Regex rx = new Regex(@"set\s+(g\S+)\s*=\s*(.*)\s*");
                    Match m = rx.Match(line);
                    //除去空格
                    string var = m.Groups[1].Value;
                    string[] value = shellwords(m.Groups[2].Value.Trim(chrTrim).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                    do_info.Add(var, value);
                }
                //读取完了，可以关闭文件了
                sr.Close();
                //正常情况下，还是要删除文件的。
                File.Delete(csh_file);
            }
        }

        private string[] shellwords(string[] value)
        {
            ArrayList shellStrings = new ArrayList();
            foreach(string item in value)
            {
                //去除每一组值的单引号
                shellStrings.Add(item.Replace("'", ""));
            }
            return (string[]) shellStrings.ToArray(typeof(string));
        }
        /// <summary>
        /// 从管道中后去返回的信息
        /// </summary>
        private string getReply()
        {
           return Console.ReadLine();
        } 

        /// <summary>
        /// 获取环境变量
        /// </summary>
        private string getENV(string envName)
        {
            return Environment.GetEnvironmentVariable(envName);
        }



        /// <summary>
        /// 从字典里面读取值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Object getInfo(string name)
        {
            int varCount = do_info[name].Count();
            if (varCount == 1)
            {
                return do_info[name][0];
            } else
            {
                return do_info[name];
            }
         
        }
    }
}
